package array;

import org.junit.Test;

import java.io.*;

/***
 * @author lyj
 * 2024-3-15
 */
//五子棋
//二维数组转稀疏数组
public class SparseArray {

    public static final String url = "E:"+ File.separator+"idea" +
            File.separator+"DataStructureAndAlgorithms" +
            File.separator+"src" +
            File.separator+"main" +
            File.separator+"resources"+
            File.separator+"map.data";
    //当前项目下resources路径

    @Test
    public void changeToSparse(){
        //定义一个11 * 11 的二维数组
        //1 是黑子   2 是篮子
        int [][] cheers=new int[11][11];
        cheers[1][1]=1;
        cheers[2][2]=1;
        cheers[3][3]=2;
        cheers[3][4]=2;
        //打印二维数组
        for (int []arr : cheers){
            for (int s:arr){
                System.out.printf("%d\t",s);
            }
            System.out.println();
        }
        /**  定义一个稀疏数组 [num+1][3]
              row  col  val
           0  11   11  二维数组里大于0的个数   统计的一行
           1  1    1     1       开始
           2
         */
        //统计大于0 的个数
        int sum=0;
        for (int []arr : cheers){
            for (int s:arr){
                if(s!=0){
                    sum++;
                }
            }
        }
        System.out.println("总个数:"+sum);
        int [][] sparseArray=new int[sum+1][3];
        //设置初始值
        sparseArray[0][0]=cheers.length;
        sparseArray[0][1]=cheers.length;
        sparseArray[0][2]=sum;
        //遍历二维数组  把大于0 的值 保存到稀疏数组
        //设置一个计数器  count
        int count=0;
        for (int i = 0; i <cheers.length ; i++) {
            for (int j = 0; j <cheers.length ; j++) {
                if(cheers[i][j]!=0){
                    count++; //count=1  第一行已经初始化值了
                    sparseArray[count][0]=i;
                    sparseArray[count][1]=j;
                    sparseArray[count][2]=cheers[i][j];
                }
            }
        }

        //打印稀疏数组
        System.out.println();
        for (int []arr : sparseArray){
            for (int s:arr){
                System.out.printf("%d\t",s);
            }
            System.out.println();
        }



        //然后重新把稀疏数组 => 二维数组
        int[][] cheer2=new int[ sparseArray[0][0]][ sparseArray[0][1]];
        System.out.println("稀疏数组长度"+sparseArray.length);
        for (int i =1; i <sparseArray.length ; i++) {
           cheer2[sparseArray[i][0]][sparseArray[i][1]]=sparseArray[i][2];
        }

        //重新打印稀疏数组导入的二维数组 cheer2
        System.out.println();
        for (int []arr : cheer2){
            for (int s:arr){
                System.out.printf("%d\t",s);
            }
            System.out.println();
        }
    }
    //测试 二维数组=》稀疏数组=》磁盘 =》稀疏数组 =》二维数组
    @Test
    public  void test(){
        int [][] cheers=new int[11][11];
        cheers[1][1]=1;
        cheers[2][2]=1;
        cheers[3][3]=2;
        cheers[3][4]=2;
        //统计大于0 的个数
        int sum=0;
        for (int []arr : cheers){
            for (int s:arr){
                if(s!=0){
                    sum++;
                }
            }
        }
        int [][] sparseArray=new int[sum+1][3];
        //设置初始值
        sparseArray[0][0]=cheers.length;
        sparseArray[0][1]=cheers.length;
        sparseArray[0][2]=sum;
        //遍历二维数组  把大于0 的值 保存到稀疏数组
        //设置一个计数器  count
        int count=0;
        for (int i = 0; i <cheers.length ; i++) {
            for (int j = 0; j <cheers.length ; j++) {
                if(cheers[i][j]!=0){
                    count++; //count=1  第一行已经初始化值了
                    sparseArray[count][0]=i;
                    sparseArray[count][1]=j;
                    sparseArray[count][2]=cheers[i][j];
                }
            }
        }
        //稀疏数组 存到本地磁盘  map.data
        OutPutMemory(url,sparseArray);
        //读取map.dta里的数据
       String array=InPutMemory(url);
       //\t分割
        System.out.println(array);
        String[] arr = array.split("\t");
        System.out.println(arr.length);
        //三个为一行
        int [][] cheersArray=new int[Integer.parseInt(arr[0])][Integer.parseInt(arr[1])];
        int g=0;
        for (int i =3; i < arr.length-1 ; i+=3) {
            // 遍历稀疏数组
            //从第二行开始给数组赋值
                cheersArray[Integer.parseInt(arr[i])][Integer.parseInt(arr[i+1])]=Integer.parseInt(arr[i+2]);
        }

        //遍历新数组 cheersArray
        System.out.println();
        for (int []ca : cheersArray){
            for (int s:ca){
                System.out.printf("%d\t",s);
            }
            System.out.println();
        }


    }

    //五子棋数组 =》 稀疏数组 存到本地磁盘  map.data
    public void OutPutMemory(String url,int[][] arr){
        try(BufferedOutputStream  outputStream=new BufferedOutputStream(new FileOutputStream(url))){
            for(int [] row:arr){
                for(int num:row){
                  //因为以二进制文件方式读取和存储  写入int类型,打开文件是二进制的
                    String str=num+"\t";
                    byte[] bytes=str.getBytes("UTF-8");
                    outputStream.write(bytes);
                }
//                outputStream.write("\n".getBytes("UTF-8"));
            }
            outputStream.close();
        }catch (Exception e){
           e.printStackTrace();
        }
    }
    //从本地磁盘读取map.data文件=>生成稀疏数组=》五子棋数组
    public String InPutMemory(String url){
        String s=null;
        try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream(url))){
            byte[]buffer=new byte[512];
            int len=0;
            while((len=bis.read(buffer))!=-1){
                 s = new String(buffer, 0, len, "UTF-8");
            }
            bis.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return s;
    }

}
